﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Atosenet.Data
{
    public abstract class PacketPayload : BaseCollection<PayloadItem>, IVerifiable, IRawData
    {
        #region 成员



        #endregion


        #region 初始化

        public PacketPayload(byte[] data)
        {
            RawData = data;
            IsValid = Verify();
        }

        #endregion


        #region 公开函数

        public virtual bool Verify()
        {
            return VerifyIntegrity(RawData) && ParseContent(RawData) && VerifyEachPayloadItem();
        }

        public override string ToString()
        {
            return "PacketPayload";
        }

        public virtual string ToString(string para)
        {
            if (string.IsNullOrEmpty(para))
                return ToString();

            switch (para.ToUpper())
            {
                case "L":
                    return string.Format("{0}[{1}]", ToString(), DataLength.ToString());
                case "D":
                    return GetDetailInfo();
                default:
                    return ToString();
            }
        }

        public bool GetPayload<T>(int index, out T payload)
        {
            payload = default(T);

            if (index >= this.Count)
                return false;

            try
            {
                payload = GenericCast<PayloadItem, T>(this[index]);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public T GetPayload<T>(int index)
        {
            T result = default(T);
            GetPayload<T>(index, out result);
            return result;
        }

        private static V GenericCast<U, V>(U obj)
        {
            return (V)Convert.ChangeType(obj, typeof(V));
        }

        #endregion


        #region 静态函数

        public static bool IsNullOrInvalid(PacketPayload pPayload)
        {
            return pPayload == null || !pPayload.IsValid;
        }

        #endregion


        #region 核心函数

        protected virtual bool VerifyIntegrity(byte[] data)
        {
            return data != null && (IsFixedFormat ? data.Length == DataLength : data.Length >= DataLength);
        }

        protected abstract bool ParseContent(byte[] data);

        protected virtual bool VerifyEachPayloadItem()
        {
             return this.TrueForAll(item => { return item.IsValid; });
        }

        protected virtual string GetDetailInfo()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("{0}[", ToString());

            for (int i = 0; i < this.Count; i++)
            {
                sb.AppendFormat("{0},", this[i].ToString("D"));
            }
            sb = sb.Remove(sb.Length - 1, 1);
            sb.Append("]");
            return sb.ToString();
        }

        #endregion


        #region 属性

        public byte[] RawData
        {
            get;
            protected set;
        }

        public bool IsValid
        {
            get;
            protected set;
        }

        public int DataLength
        {
            get { return RawData.Length; }
        }

        public abstract bool IsFixedFormat
        {
            get;
        }

        #endregion
    }
}
